package com.lmaye.eshop.inventory.thread;

import com.lmaye.eshop.inventory.request.ProductInventoryCacheRefreshRequest;
import com.lmaye.eshop.inventory.request.ProductInventoryDbUpdateRequest;
import com.lmaye.eshop.inventory.request.Request;
import com.lmaye.eshop.inventory.request.RequestMemoryQueue;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;

/**
 * <pre>
 *   ┏┓　　　┏┓
 * ┏┛┻━━━┛┻┓
 * ┃　　　　　　　┃
 * ┃　　　━　　　┃
 * ┃　┳┛　┗┳　┃
 * ┃　　　　　　　┃
 * ┃　　　┻　　　┃
 * ┃　　　　　　　┃
 * ┗━┓　　　┏━┛
 * 　　┃　　　┃神兽保佑
 * 　　┃　　　┃代码无BUG！
 * 　　┃　　　┗━━━┓
 * 　　┃　　　　　　　┣┓
 * 　　┃　　　　　　　┏┛
 * 　　┗┓┓┏━┳┓┏┛
 * 　　　┃┫┫　┃┫┫
 * 　　　┗┻┛　┗┻┛
 * </pre>
 * -- 执行请求的工作线程
 *
 * @author lmay.Zhou
 * @date 2019/3/12 23:45 星期二
 * @qq 379839355
 * @email lmay@lmaye.com
 */
public class RequestProcessorThread implements Callable<Boolean> {
    /**
     * 监控的内存队列
     */
    private ArrayBlockingQueue<Request> queue;

    public RequestProcessorThread(ArrayBlockingQueue<Request> queue) {
        this.queue = queue;
    }

    @Override
    public Boolean call() throws Exception {
        try {
            while(true) {
                // ArrayBlockingQueue Blocking就是说如果队列满了或者是空的，那么都会在执行操作的时候，阻塞住
                Request request = queue.take();
                boolean forceRefresh = request.isForceRefresh();
                // 是否强制刷新缓存
                if(!forceRefresh) {
                    RequestMemoryQueue requestMemoryQueue = RequestMemoryQueue.getInstance();
                    Map<Integer, Boolean> flagMap = requestMemoryQueue.getFlagMap();
                    Integer productId = request.getProductId();

                    if(request instanceof ProductInventoryDbUpdateRequest) {
                        // 如果是一个更新数据库的请求，那么就将那个productId对应的标识设置为true
                        flagMap.put(productId, true);
                    } else if(request instanceof ProductInventoryCacheRefreshRequest) {
                        // 如果是一个缓存刷新的请求
                        Boolean flag = flagMap.get(productId);
                        // 如果flag标识是null
                        if(Objects.isNull(flag)) {
                            flagMap.put(productId, false);
                        }
                        // 如果标识不为null，而且是true，就说明之前有一个这个商品的数据更新请求
                        if(Objects.nonNull(flag) && flag) {
                            flagMap.put(productId, false);
                        }
                        // 如果标识不为null，但是标识是false，说明前面已经有一个数据库更新请求 + 一个缓存刷新请求
                        if(Objects.nonNull(flag) && !flag) {
                            // 对于这种请求，直接就过滤掉，不要放到后面的内存队列里面去了
                            return true;
                        }
                    }
                }
                // 执行这个request操作
                request.process();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}
